#include "http_server_impl.h"
#include "base_log.h"
#include <mongoose.h>
#include <cstring>
#include <memory>
#include <chrono>
#include <thread>
#include <unistd.h>
#include <sys/stat.h>
#include <filesystem>
#include "base_file_util.h"
#include <regex>

namespace El {
namespace WebServer {

IHttpServer &IHttpServer::GetInstance()
{
    return HttpServerImpl::GetInstance();
}

HttpServerImpl &HttpServerImpl::GetInstance()
{
    static HttpServerImpl instance;
    return instance;
}

HttpServerImpl::HttpServerImpl() {}

HttpServerImpl::~HttpServerImpl()
{
    Stop();
}

bool HttpServerImpl::Start()
{
    if (running_) {
        return false;
    }

    mgr_ = new mg_mgr;
    mg_mgr_init(mgr_);

    const char *address = "https://0.0.0.0:80";
    mg_connection *conn = mg_http_listen(mgr_, address, HandleHttpEvent, this);
    if (conn == nullptr) {
        LOG_ERROR("Failed to start HTTPS server on {}", address);
        mg_mgr_free(mgr_);
        delete mgr_;
        mgr_ = nullptr;
        return false;
    }

    running_ = true;
    serverThread_ = std::thread([this]() {
        while (running_) {
            mg_mgr_poll(mgr_, 1000);
        }
    });

    LOG_INFO("HTTPS server started on {} with TLS enabled", address);
    return true;
}

void HttpServerImpl::Stop()
{
    if (!running_) {
        return;
    }

    running_ = false;
    if (serverThread_.joinable()) {
        serverThread_.join();
    }

    if (mgr_) {
        mg_mgr_free(mgr_);
        delete mgr_;
        mgr_ = nullptr;
    }

    LOG_INFO("HTTPS server stopped");
}

bool HttpServerImpl::RegisterWebSocketHandler(const std::string &uri_pattern, WebSocketEventHandler handler)
{
    // 创建WebSocket路由项
    WebSocketRouteItem route;
    route.uri_pattern = uri_pattern;
    route.handler = handler;

    try {
        route.uri_regex = std::regex(uri_pattern);
    } catch (const std::regex_error &e) {
        LOG_ERROR("Invalid WebSocket URI pattern: {}, error: {}", uri_pattern, e.what());
        return false;
    }

    // 添加到WebSocket路由表
    ws_routes_.push_back(route);

    LOG_INFO("WebSocket handler registered for pattern: {}", uri_pattern);
    return true;
}

bool HttpServerImpl::SendWebSocketTextMessage(void *connection, const std::string &message)
{
    auto *c = static_cast<mg_connection *>(connection);
    if (c != nullptr && c->is_websocket) {
        mg_ws_send(c, message.c_str(), message.size(), WEBSOCKET_OP_TEXT);
        return true;
    }
    return false;
}

bool HttpServerImpl::SetMountPoint(const std::string &dir)
{
    root_dir_ = dir;
    LOG_INFO("Web root directory set to: {}", dir);
    return true;
}

bool HttpServerImpl::RegisterHandler(const std::string &method, const std::string &uri_pattern, HttpHandler handler)
{
    try {
        RouteItem route{method, uri_pattern, handler, std::regex(uri_pattern)};
        routes_.push_back(route);
        LOG_INFO("Handler registered for method: {}, URI pattern: {}", method, uri_pattern);
        return true;
    } catch (const std::regex_error &e) {
        LOG_ERROR("Invalid regex pattern: {}, error: {}", uri_pattern, e.what());
        return false;
    }
}

bool HttpServerImpl::MatchRoute(const std::string &method, const std::string &uri, RouteItem *route)
{
    // 首先检查普通HTTP路由
    for (const auto &r : routes_) {
        if (r.method == method && std::regex_match(uri, r.uri_regex)) {
            if (route != nullptr) {
                *route = r;
            }
            return true;
        }
    }

    return false;
}

bool HttpServerImpl::FindWebSocketRoute(const std::string &uri, WebSocketRouteItem *route)
{
    for (const auto &r : ws_routes_) {
        if (std::regex_match(uri, r.uri_regex)) {
            if (route != nullptr) {
                *route = r;
            }
            return true;
        }
    }

    return false;
}

bool HttpServerImpl::ValidateToken(const std::string &token)
{
    // 如果没有设置任何token，则返回失败
    if (bearer_tokens_.empty()) {
        LOG_WARN("No bearer tokens set");
        return false;
    }

    // 检查token是否在已授权集合中
    return HasBearerToken(token);
}

bool HttpServerImpl::IsAuthExempt(const std::string &uri)
{
    // 检查是否匹配任一免鉴权正则表达式
    for (const auto &pattern : auth_exempt_urls_) {
        if (std::regex_match(uri, pattern)) {
            return true;
        }
    }
    return false;
}

bool HttpServerImpl::ValidateAuthHeader(const mg_str *auth_header)
{
    if (auth_header == nullptr) {
        return false;
    }

    std::string auth_str(auth_header->ptr, auth_header->len);
    if (auth_str.substr(0, 7) != "Bearer ") {
        return false;
    }

    std::string token = auth_str.substr(7);
    return ValidateToken(token);
}

void HttpServerImpl::HandleHttpRequest(mg_connection *c, int ev, void *ev_data)
{
    (void)ev;
    struct mg_http_message *hm = (struct mg_http_message *)ev_data;

    // 提取请求方法和URI
    std::string method(hm->method.ptr, hm->method.len);
    std::string uri(hm->uri.ptr, hm->uri.len);

    // 提取不带查询参数的路径部分，用于路由匹配
    std::string path = uri;
    size_t queryPos = uri.find('?');
    if (queryPos != std::string::npos) {
        path = uri.substr(0, queryPos);
    }

    LOG_DEBUG("Received HTTP request: {} {}, path: {}", method, uri, path);

    // 检查是否有鉴权豁免
    bool isExempt = IsAuthExempt(path);

    // 尝试匹配WebSocket路由
    WebSocketRouteItem wsRoute;
    bool isWebSocketRequest = mg_http_get_header(hm, "Upgrade") != nullptr && // 检查是否包含WebSocket升级头
                              FindWebSocketRoute(path, &wsRoute);
    if (isWebSocketRequest) {
        // 保存连接与URI的映射关系，以便后续事件处理时使用
        ws_connection_uris_[c] = path;

        // WebSocket连接不需要鉴权，直接升级
        LOG_INFO("WebSocket connection upgraded: {} {}", method, path);
        mg_ws_upgrade(c, hm, NULL);
        return;
    } else {
        // 尝试匹配普通HTTP路由
        RouteItem route;
        if (MatchRoute(method, path, &route)) {
            // 检查是否需要鉴权
            if (!isExempt) {
                struct mg_str *auth_header = mg_http_get_header(hm, "Authorization");
                if (!ValidateAuthHeader(auth_header)) {
                    LOG_WARN("HTTP request rejected: unauthorized, uri: {}", path);
                    mg_http_reply(c, 401, nullptr, "Unauthorized");
                    return;
                }
            }

            // 构建请求对象
            HttpRequest request;
            request.method = method;
            request.uri = path;
            request.body = std::string(hm->body.ptr, hm->body.len);

            // 获取请求头
            for (size_t i = 0; i < MG_MAX_HTTP_HEADERS && hm->headers[i].name.len > 0; i++) {
                auto &h = hm->headers[i];
                request.headers[std::string(h.name.ptr, h.name.len)] = std::string(h.value.ptr, h.value.len);
            }

            // 调用处理函数获取响应
            HttpResponse response = route.handler(request);

            // 使用mg_http_reply发送响应
            mg_http_reply(c, response.status_code, ("Content-Type: " + response.content_type + "\r\n").c_str(), "%s",
                          response.body.c_str());
        } else {
            // 没有匹配的路由，提供静态文件服务
            struct mg_http_serve_opts opts = {.root_dir = root_dir_.c_str(),
                                              .ssi_pattern = nullptr,
                                              .extra_headers = "Cache-Control: no-cache\r\n",
                                              .mime_types = nullptr,
                                              .page404 = nullptr,
                                              .fs = nullptr};
            mg_http_serve_dir(c, hm, &opts);
        }
    }
}

void HttpServerImpl::HandleHttpEvent(mg_connection *c, int ev, void *ev_data, void *fn_data)
{
    auto *server = static_cast<HttpServerImpl *>(fn_data);
    if (server == nullptr) {
        return;
    }

    switch (ev) {
        case MG_EV_HTTP_MSG: {
            LOG_INFO("HTTP message received");
            server->HandleHttpRequest(c, ev, ev_data);
            break;
        }
        case MG_EV_WS_OPEN: {
            LOG_INFO("WebSocket connection opened");

            // 通过映射表找到连接对应的URI
            auto it = server->ws_connection_uris_.find(c);
            if (it != server->ws_connection_uris_.end()) {
                const std::string &uri = it->second;
                LOG_DEBUG("WebSocket opened for URI: {}", uri);

                // 查找匹配的WebSocket处理器
                WebSocketRouteItem route;
                if (server->FindWebSocketRoute(uri, &route)) {
                    auto event = std::make_shared<WebSocketEvent>();
                    event->type = WebSocketEventType::Connect;
                    event->connection = c;
                    route.handler(event);
                } else {
                    LOG_WARN("No WebSocket handler found for URI: {}", uri);
                }
            } else {
                LOG_ERROR("WebSocket connection opened but URI not found in connection map");
            }
            break;
        }
        case MG_EV_WS_MSG: {
            LOG_DEBUG("WebSocket message received");
            auto *wm = static_cast<mg_ws_message *>(ev_data);

            // 通过映射表找到连接对应的URI
            auto it = server->ws_connection_uris_.find(c);
            if (it != server->ws_connection_uris_.end()) {
                const std::string &uri = it->second;

                // 查找匹配的WebSocket处理器
                WebSocketRouteItem route;
                if (server->FindWebSocketRoute(uri, &route)) {
                    auto event = std::make_shared<WebSocketEvent>();
                    event->type = WebSocketEventType::Message;
                    event->connection = c;
                    event->message = std::string(wm->data.ptr, wm->data.len);
                    route.handler(event);
                } else {
                    LOG_WARN("No WebSocket handler found for URI: {}", uri);
                }
            } else {
                LOG_ERROR("WebSocket message received but URI not found in connection map");
            }
            break;
        }
        case MG_EV_CLOSE: {
            LOG_DEBUG("Connection closed");
            if (c->is_websocket) {
                // 通过映射表找到连接对应的URI
                auto it = server->ws_connection_uris_.find(c);
                if (it != server->ws_connection_uris_.end()) {
                    const std::string &uri = it->second;

                    // 查找匹配的WebSocket处理器
                    WebSocketRouteItem route;
                    if (server->FindWebSocketRoute(uri, &route)) {
                        auto event = std::make_shared<WebSocketEvent>();
                        event->type = WebSocketEventType::Disconnect;
                        event->connection = c;
                        route.handler(event);
                    } else {
                        LOG_DEBUG("No WebSocket handler found for closed URI: {}", uri);
                    }

                    // 从映射表中移除连接
                    server->ws_connection_uris_.erase(it);
                } else {
                    LOG_ERROR("WebSocket connection closed but URI not found in connection map");
                }
            }
            break;
        }
        case MG_EV_ERROR: {
            LOG_ERROR("Connection error: {}", (const char *)ev_data);
            break;
        }
        default:
            break;
    }
}

void HttpServerImpl::SetSSLCert(const std::string &cert_file, const std::string &key_file)
{
    cert_file_ = cert_file;
    key_file_ = key_file;
}

void HttpServerImpl::AddBearerToken(const std::string &token)
{
    bearer_tokens_.insert(token);
}

void HttpServerImpl::RemoveBearerToken(const std::string &token)
{
    bearer_tokens_.erase(token);
}

bool HttpServerImpl::HasBearerToken(const std::string &token)
{
    return bearer_tokens_.find(token) != bearer_tokens_.end();
}

void HttpServerImpl::AddAuthExemptUrl(const std::string &url_pattern)
{
    try {
        auth_exempt_urls_.emplace_back(url_pattern);
    } catch (const std::regex_error &e) {
        LOG_ERROR("Invalid regex pattern for auth exempt URL: {}, error: {}", url_pattern, e.what());
    }
}

void HttpServerImpl::RemoveAuthExemptUrl(const std::string &url_pattern)
{
    // 移除所有匹配的正则表达式字符串
    auth_exempt_urls_.erase(std::remove_if(auth_exempt_urls_.begin(), auth_exempt_urls_.end(),
                                           [&url_pattern](const std::regex &r) {
                                               return r.flags() == std::regex::ECMAScript && r.mark_count() == 0 &&
                                                      std::regex_match(url_pattern, r);
                                           }),
                            auth_exempt_urls_.end());
}

bool HttpServerImpl::SendWebSocketBinaryMessage(void *connection, const std::vector<uint8_t> &data)
{
    if (connection == nullptr || data.empty()) {
        return false;
    }

    auto *c = static_cast<mg_connection *>(connection);
    if (c != nullptr && c->is_websocket) {
        mg_ws_send(c, data.data(), data.size(), WEBSOCKET_OP_BINARY);
        return true;
    }
    return false;
}

void HttpServerImpl::CloseWebSocketConnection(void *connection, int status_code, const std::string &reason)
{
    if (connection == nullptr) {
        return;
    }

    auto *c = static_cast<mg_connection *>(connection);
    if (c->is_websocket) {
        // 发送WebSocket关闭帧
        if (status_code > 0) {
            uint16_t code = static_cast<uint16_t>(status_code);
            std::vector<uint8_t> close_data;

            // 添加关闭状态码（网络字节序）
            close_data.push_back(static_cast<uint8_t>(code >> 8));
            close_data.push_back(static_cast<uint8_t>(code & 0xFF));

            // 添加关闭原因
            close_data.insert(close_data.end(), reason.begin(), reason.end());

            // 发送关闭帧
            mg_ws_send(c, close_data.data(), close_data.size(), WEBSOCKET_OP_CLOSE);
        }

        // 向所有WebSocket处理器发送关闭事件
        auto it = ws_connection_uris_.find(c);
        if (it != ws_connection_uris_.end()) {
            const std::string &uri = it->second;
            WebSocketRouteItem route;
            if (FindWebSocketRoute(uri, &route)) {
                auto event = std::make_shared<WebSocketEvent>();
                event->type = WebSocketEventType::Disconnect;
                event->connection = c;
                event->message = reason;
                route.handler(event);
            }
        }

        // 关闭连接
        c->is_closing = 1;
        LOG_INFO("WebSocket connection closed with status code: {}, reason: {}", status_code, reason);
    }
}

bool HttpServerImpl::GetWebSocketConnectionInfo(void *connection, WebSocketConnectionInfo &info)
{
    if (connection == nullptr) {
        return false;
    }

    auto *c = static_cast<mg_connection *>(connection);
    if (!c->is_websocket) {
        return false;
    }

    // 获取连接信息
    auto it = ws_connection_infos_.find(c);
    if (it != ws_connection_infos_.end()) {
        info = it->second;
        return true;
    }

    // 如果没有缓存的信息，尝试从连接对象中获取
    auto uri_it = ws_connection_uris_.find(c);
    if (uri_it != ws_connection_uris_.end()) {
        info.uri = uri_it->second;

        // 获取远程地址信息
        info.remote_ip = std::string((const char *)c->rem.ip, 16);
        info.remote_port = mg_ntohs(c->rem.port);

        // 是否为安全连接
        info.is_secure = c->is_tls;

        // 设置连接时间为当前时间（如果没有记录）
        info.connect_time = std::chrono::system_clock::now();

        // 缓存连接信息
        ws_connection_infos_[c] = info;

        return true;
    }

    return false;
}

std::vector<void *> HttpServerImpl::GetAllWebSocketConnections(const std::string &uri_pattern)
{
    std::vector<void *> connections;

    if (uri_pattern.empty()) {
        // 返回所有WebSocket连接
        for (const auto &pair : ws_connection_uris_) {
            connections.push_back(static_cast<void *>(pair.first));
        }
    } else {
        // 尝试编译正则表达式
        std::regex uri_regex;
        try {
            uri_regex = std::regex(uri_pattern);
        } catch (const std::regex_error &e) {
            LOG_ERROR("Invalid URI pattern for WebSocket connections: {}, error: {}", uri_pattern, e.what());
            return connections;
        }

        // 返回匹配的WebSocket连接
        for (const auto &pair : ws_connection_uris_) {
            if (std::regex_match(pair.second, uri_regex)) {
                connections.push_back(static_cast<void *>(pair.first));
            }
        }
    }

    return connections;
}

int HttpServerImpl::BroadcastWebSocketMessage(const std::string &uri_pattern, const std::string &message)
{
    if (message.empty()) {
        return 0;
    }

    // 获取匹配的WebSocket连接
    std::vector<void *> connections = GetAllWebSocketConnections(uri_pattern);

    // 发送消息
    int sent_count = 0;
    for (void *conn : connections) {
        if (SendWebSocketTextMessage(conn, message)) {
            sent_count++;
        }
    }

    LOG_INFO("WebSocket broadcast to {} connections, pattern: {}", sent_count, uri_pattern);
    return sent_count;
}

} // namespace WebServer
} // namespace El